package com.olive.config;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import com.alibaba.fastjson.JSON;

import reactor.core.publisher.Mono;

/**
 * 鉴权失败处理器
 */
//@Component
public class DefaultServerAccessDeniedHandler implements ServerAccessDeniedHandler {

	@Override
	public Mono<Void> handle(ServerWebExchange exchange, AccessDeniedException e) {
		return Mono.defer(() -> Mono.just(exchange.getResponse())).flatMap(response -> {
			response.setStatusCode(HttpStatus.FORBIDDEN);
			response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
			DataBufferFactory dataBufferFactory = response.bufferFactory();
			DataBuffer buffer = dataBufferFactory.wrap(getJsonOutputException(e));
			return response.writeWith(Mono.just(buffer)).doOnError(error -> DataBufferUtils.release(buffer));
		});
	}

	public byte[] getJsonOutputException(AccessDeniedException accessDeniedException) {
		int code = 402;
		if (accessDeniedException instanceof CustomAccessDeniedException) {
			CustomAccessDeniedException ex = (CustomAccessDeniedException) accessDeniedException;
			code = ex.getCode();
		}
		Map<String, Object> response = new HashMap<>();
		response.put("code", code);
		response.put("msg", accessDeniedException.getMessage());
		return JSON.toJSONString(response).getBytes(StandardCharsets.UTF_8);
	}

}